struct cdq_cdq_bit_t{ // CDQ套CDQ套树状数组，四维偏序, 前三维各不相同

struct FenwickTree{ // 树状数组

using value_type = long long int;
using vec_type = vector<value_type>;

int n;
vec_type c;

FenwickTree() = default;

static int lowbit(int x){return x & -x;}

void init(int nn){this->c.assign((this->n=nn) + 1, 0);}

void modify(int pos, value_type delta){
    for(int i=pos;i<=this->n;i+=lowbit(i)) this->c[i] += delta;
}

void clear(int pos){
    for(int i=pos;i<=this->n;i+=lowbit(i)) this->c[i] = 0;
}

value_type query(int pos)const{
    value_type ans = 0;
    for(int i=pos;i;i-=lowbit(i)) ans += this->c[i];
    return ans;
}

value_type query(int s, int e)const{return this->query(e) - this->query(s - 1);}

}Bt;

using value_t = int;
using cmp_t = function<bool(value_t, value_t)>;

struct _t{
    value_t x;
    value_t y;
    value_t z;
    value_t w;
    int pos;
    int flag;
};

int N;
vector<_t> A, B, C;
cmp_t cmp1, cmp2, cmp3, cmp4;

void setCmp(cmp_t c1, cmp_t c2, cmp_t c3, cmp_t c4) {
    cmp1 = c1; cmp2 = c2; cmp3 = c3; cmp4 = c4;
}

void input() {
    cin >> N;
    A.assign(N, {});
    B.assign(N, {});
    C.assign(N, {});
    int k = 0;
    for(auto & p : A){
        cin >> p.x >> p.y >> p.z >> p.w;
        p.pos = k++;
    }
    return;
}

vector<int> Ans;
vector<value_t> W;

void run() {
    Ans.assign(N, 0);

    /// 按第一维排序
    sort(A.begin(), A.end(), [this](const _t & a, const _t & b){
        if(a.x != b.x) return this->cmp1(a.x, b.x);
        if(a.y != b.y) return this->cmp2(a.y, b.y);
        if(a.z != b.z) return this->cmp3(a.z, b.z);
        if(a.w != b.w) return this->cmp4(a.w, b.w);
        if(a.pos != b.pos) return a.pos < b.pos;
        return a.flag < b.flag;
    });
    
    /// 对w坐标做离散化
    W.clear(); W.reserve(N + 2);
    W.emplace_back(INT_MIN);
    for(const auto & p : A) W.emplace_back(p.w);
    W.emplace_back(INT_MAX);
    sort(W.begin(), W.end(), this->cmp4);
    W.erase(unique(W.begin(), W.end()), W.end());
    
    int n = W.size();
    Bt.init(n);

    CDQ(0, N - 1);

    return;
}

void CDQ(int s, int e){
    if(s >= e) return;

    int mid = (s + e) >> 1;
    CDQ(s, mid); CDQ(mid + 1, e);

    /// 在第一维处标注好第二维的大小关系
    int u = s, v = mid + 1, t = s;
    while(u <= mid and v <= e){
        if(this->cmp2(A[u].y, A[v].y)){
            A[u].flag = 1;
            B[t++] = A[u++];
        }else{
            A[v].flag = 0;
            B[t++] = A[v++];
        }
    }
    while(u <= mid){
        A[u].flag = 1;
        B[t++] = A[u++];
    }
    while(v <= e){
        A[v].flag = 0;
        B[t++] = A[v++];
    }

    copy(B.begin() + s, B.begin() + e + 1, A.begin() + s);
    CDQ2(s, e);
    return;
}

void CDQ2(int s, int e){
    if(s >= e) return;
    int mid = (s + e) >> 1;
    CDQ2(s, mid); CDQ2(mid + 1, e);

    int u = s, v = mid + 1, t = s;
    while(u <= mid and v <= e){
        if(this->cmp3(B[u].z, B[v].z)){
            if(B[u].flag){
                auto p = lower_bound(W.begin(), W.end(), B[u].w, this->cmp4) - W.begin();
                Bt.modify(p, 1);
            }
            C[t++] = B[u++];
        }else{
            if(not B[v].flag){
                auto p = lower_bound(W.begin(), W.end(), B[v].w, this->cmp4) - W.begin();
                Ans[B[v].pos] += Bt.query(p - 1); 
            }
            C[t++] = B[v++];
        }
    }
    while(u <= mid){
        C[t++] = B[u++];
    }
    while(v <= e){
        if(not B[v].flag){
            auto p = lower_bound(W.begin(), W.end(), B[v].w, this->cmp4) - W.begin();
            Ans[B[v].pos] += Bt.query(p - 1);
        }
        C[t++] = B[v++];
    }

    /// 清空树状数组
    for(int i=s;i<=e;++i){
        if(C[i].flag){
            auto p = lower_bound(W.begin(), W.end(), C[i].w, this->cmp4) - W.begin();
            Bt.clear(p);            
        }

    }

    copy(C.begin() + s, C.begin() + e + 1, B.begin() + s);
    return;
}

};